// SupportHangerSelector.h: interface for the SupportHangerSelector class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SUPPORTHANGERSELECTOR_H__2D808446_2982_480B_BA99_C4E60A190A18__INCLUDED_)
#define AFX_SUPPORTHANGERSELECTOR_H__2D808446_2982_480B_BA99_C4E60A190A18__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "SupportHanger.h"

namespace SHSelector
{
	struct HandleStratigy
	{
	public:
		virtual BOOL GetHandle(AcDbHandle& handle) = 0;
	};

	struct ChooseInGMS : public HandleStratigy
	{
	public:
		virtual BOOL GetHandle(AcDbHandle& handle);
	};

	struct SHChooseInGMS
	{
	public:
		INT GetHandle(AcDbHandle& handle);
		SupportHanger * GetSupportHanger();
	};

	struct SHParserStratigy
	{
	public:
		virtual SupportHanger* Parser(AcDbHandle& handle) = 0;
	};

	struct SHXDataParser : public SHParserStratigy
	{
	public:
		virtual SupportHanger* Parser(AcDbHandle& handle);
	};

	struct PartParserStratigy
	{
	public:
		virtual Part* Parser(AcDbHandle& handle) = 0;
	};

	struct PartXDataParser : public PartParserStratigy
	{
	public:
		virtual Part* Parser(AcDbHandle& handle);
	};

	struct SHCheckStratigy
	{
	public:
		virtual BOOL IsLegal(SupportHanger* pSH) = 0;
	};

	struct SHDefaultStratigy : public SHCheckStratigy
	{
	public:
		virtual BOOL IsLegal(SupportHanger* pSH){
			return TRUE;
		}
	};

	struct SHCheckOut : public SHCheckStratigy
	{
	public:
		virtual BOOL IsLegal(SupportHanger* pSH);
	};

	struct PartCheckStratigy
	{
	public:
		virtual BOOL IsLegal(Part* pPart){
			return TRUE;
		}
	};

	template 
		<
		class _SelectorType,
		class _HandleStratigy,
		class _ParserStratigy,
		class _CheckStratigy
		>
		class Selector  
	{
		typedef _SelectorType* typePtr;
		
	public:
		enum SelectorStatus{
			eCANCEL,
			eOK
		};
public:
	Selector(){
		m_Status = eOK;
	}
	virtual ~Selector(){}
	
public:
	typePtr Select(){
		AcDbHandle handle;
		typePtr pObj = 0;

		_HandleStratigy handle_;
		_ParserStratigy parser_;
		_CheckStratigy check_;

		while(TRUE)
		{
			if(!handle_.GetHandle(handle))
			{
				m_Status = eCANCEL;
				return NULL;
			}
			
			if((pObj = parser_.Parser(handle)) == NULL)
				continue;
			if(check_.IsLegal(pObj))
				return pObj;
		}

	}
	
	SelectorStatus Status() {
		return m_Status;
	}
	
private:
	SelectorStatus m_Status;
	};
	
	template<> class Selector<SupportHanger, SHChooseInGMS, SHXDataParser, SHCheckOut>
	{
		typedef SupportHanger* typePtr;
		
	public:
		enum SelectorStatus{
			eCANCEL,
			eOK,
			eENTERSHID
		};
	public:
		Selector(){
			m_Status = eOK;
		}
		virtual ~Selector(){}
		
	public:
		typePtr Select(){
			AcDbHandle handle;
			typePtr pObj = 0;
			
			SHChooseInGMS handle_;
			SHXDataParser parser_;
			SHCheckOut check_;
			INT nState = 0;

			while(TRUE)
			{
				nState = handle_.GetHandle(handle);

				if( nState == 0 )
				{
					m_Status = eCANCEL;
					return NULL;
				}
				else if(nState == 1)
				{
					if((pObj = parser_.Parser(handle)) == NULL)
						continue;
					m_Status = eOK;
				}
				else if (nState == 2) 
				{
					if((pObj = handle_.GetSupportHanger()) == NULL)
					{
						m_Status = eCANCEL;
						return NULL;
					}
					m_Status = eENTERSHID;
				}
				if(check_.IsLegal(pObj))
					return pObj;
			}
			

		}
		
		SelectorStatus Status() {
			return m_Status;
		}
		
	private:
		SelectorStatus m_Status;
	};
}

using namespace SHSelector;
typedef Selector<SupportHanger, SHChooseInGMS, SHXDataParser, SHCheckOut> SupportHangerSelector;
typedef Selector<Part, ChooseInGMS, PartXDataParser, PartCheckStratigy> PartSelector;
typedef Selector<SupportHanger, ChooseInGMS, SHXDataParser, SHDefaultStratigy> NoFilterSHSelector;

#endif // !defined(AFX_SUPPORTHANGERSELECTOR_H__2D808446_2982_480B_BA99_C4E60A190A18__INCLUDED_)
